{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "16b67939",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import pandas as pd\n",
    "import lightgbm as lgb\n",
    "import xgboost as xgb\n",
    "from catboost import CatBoostClassifier, CatBoostRegressor\n",
    "from sklearn.model_selection import StratifiedKFold, KFold, GroupKFold\n",
    "from sklearn.metrics import mean_squared_error, mean_absolute_error\n",
    "import matplotlib.pyplot as plt\n",
    "import tqdm\n",
    "import sys\n",
    "import os\n",
    "import gc\n",
    "import argparse\n",
    "import warnings\n",
    "warnings.filterwarnings('ignore')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "cbc0dc7f",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 读取数据\n",
    "train_info = pd.read_csv('./data/A榜-训练集_海上风电预测_基本信息.csv', encoding='gbk')\n",
    "train_df = pd.read_csv('./data/A榜-训练集_海上风电预测_气象变量及实际功率数据.csv', encoding='gbk')\n",
    "\n",
    "test_info = pd.read_csv('./data/B榜-测试集_海上风电预测_基本信息.csv', encoding='gbk')\n",
    "test_df = pd.read_csv('./data/B榜-测试集_海上风电预测_气象变量数据.csv', encoding='gbk')\n",
    "\n",
    "submit_example = pd.read_csv('./data/submit_example.csv')\n",
    "\n",
    "train_df = train_df.merge(train_info[['站点编号','装机容量(MW)']], on=['站点编号'], how='left')\n",
    "test_df = test_df.merge(test_info[['站点编号','装机容量(MW)']], on=['站点编号'], how='left')\n",
    "\n",
    "train_df['站点编号'] = train_df['站点编号'].apply(lambda x:int(x[1]))\n",
    "test_df['站点编号'] = test_df['站点编号'].apply(lambda x:int(x[1]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "01807853-471a-47a8-95ee-8e6805ded714",
   "metadata": {},
   "outputs": [],
   "source": [
    "train_df.columns = ['stationId','time','airPressure','relativeHumidity','cloudiness','10mWindSpeed','10mWindDirection',\n",
    "                 'temperature','irradiation','precipitation','100mWindSpeed','100mWindDirection','power','capacity']\n",
    "\n",
    "test_df.columns = ['stationId','time','airPressure','relativeHumidity','cloudiness','10mWindSpeed','10mWindDirection',\n",
    "                 'temperature','irradiation','precipitation','100mWindSpeed','100mWindDirection','capacity']\n",
    "\n",
    "# 特征组合\n",
    "train_df['100mWindSpeed/10mWindSpeed'] = train_df['100mWindSpeed'] / (train_df['10mWindSpeed'] + 0.0000001)\n",
    "test_df['100mWindSpeed/10mWindSpeed'] = test_df['100mWindSpeed'] / (test_df['10mWindSpeed'] + 0.0000001)\n",
    "\n",
    "train_df['100mWindDirection/10mWindDirection'] = train_df['100mWindDirection'] / (train_df['10mWindDirection'] + 0.0000001)\n",
    "test_df['100mWindDirection/10mWindDirection'] = test_df['100mWindDirection'] / (test_df['10mWindDirection'] + 0.0000001)\n",
    "\n",
    "train_df['10mWindDirection_new'] = train_df['10mWindDirection'] - 180\n",
    "test_df['10mWindDirection_new'] = test_df['10mWindDirection'] - 180\n",
    "\n",
    "# 差值\n",
    "train_df['100mWindSpeed_10mWindSpeed'] = train_df['100mWindSpeed'] - train_df['10mWindSpeed'] \n",
    "test_df['100mWindSpeed_10mWindSpeed'] = test_df['100mWindSpeed'] - test_df['10mWindSpeed']\n",
    "\n",
    "train_df['100mWindDirection_10mWindDirection'] = train_df['100mWindDirection'] - train_df['10mWindDirection']\n",
    "test_df['100mWindDirection_10mWindDirection'] = test_df['100mWindDirection'] - test_df['10mWindDirection']\n",
    "\n",
    "# 风切变指数\n",
    "train_df['WindSpeed/WindDirectio'] = train_df['100mWindSpeed/10mWindSpeed'] / train_df['100mWindDirection/10mWindDirection']\n",
    "test_df['WindSpeed/WindDirectio'] = test_df['100mWindSpeed/10mWindSpeed'] / test_df['100mWindDirection/10mWindDirection']\n",
    "\n",
    "train_df['100mWindSpeed/10mWindSpeed_2'] = train_df['100mWindSpeed/10mWindSpeed'].apply(lambda x:np.log10(x)) / 10\n",
    "test_df['100mWindSpeed/10mWindSpeed_2'] = test_df['100mWindSpeed/10mWindSpeed'].apply(lambda x:np.log10(x)) / 10\n",
    "\n",
    "# 湿度/温度\n",
    "train_df['relativeHumidity/temperature'] = train_df['relativeHumidity'] / (train_df['temperature'] + 0.0000001)\n",
    "test_df['relativeHumidity/temperature'] = test_df['relativeHumidity'] / (test_df['temperature'] + 0.0000001)\n",
    "\n",
    "# 辐射/温度\n",
    "train_df['irradiation/temperature'] = train_df['irradiation'] / (train_df['temperature'] + 0.0000001)\n",
    "test_df['irradiation/temperature'] = test_df['irradiation'] / (test_df['temperature'] + 0.0000001)\n",
    "\n",
    "# 辐射/云量\n",
    "train_df['irradiation/cloudiness'] = train_df['irradiation'] / (train_df['cloudiness'] + 0.0000001)\n",
    "test_df['irradiation/cloudiness'] = test_df['irradiation'] / (test_df['cloudiness'] + 0.0000001)\n",
    "\n",
    "# 是否降水\n",
    "train_df['is_precipitation'] = train_df['precipitation'].apply(lambda x:1 if x>0 else 0)\n",
    "test_df['is_precipitation'] = test_df['precipitation'].apply(lambda x:1 if x>0 else 0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "cfc9a02f-4f8c-4739-a2f4-5fea119546d8",
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_time_feature(df, col):\n",
    "    \n",
    "    df_copy = df.copy()\n",
    "    prefix = col + \"_\"\n",
    "    df_copy[col] = df_copy[col].astype(str)\n",
    "    \n",
    "    df_copy[col] = pd.to_datetime(df_copy[col], format='%Y%m%d %H:%M')\n",
    "    df_copy[prefix + 'month'] = df_copy[col].dt.month\n",
    "    df_copy[prefix + 'day'] = df_copy[col].dt.day\n",
    "    df_copy[prefix + 'hour'] = df_copy[col].dt.hour\n",
    "    df_copy[prefix + 'minute'] = df_copy[col].dt.minute\n",
    "    df_copy[prefix + 'weekofyear'] = df_copy[col].dt.weekofyear\n",
    "    df_copy[prefix + 'dayofyear'] = df_copy[col].dt.dayofyear\n",
    "    \n",
    "    return df_copy   \n",
    "\n",
    "train_df = get_time_feature(train_df, 'time')\n",
    "test_df = get_time_feature(test_df, 'time')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "b2359736-3fca-4970-b8e2-99c6f36f6c5e",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|██████████| 10/10 [03:19<00:00, 19.96s/it]\n"
     ]
    }
   ],
   "source": [
    "# 合并训练数据和测试数据\n",
    "train_df['is_test'] = 0\n",
    "test_df['is_test'] = 1\n",
    "df = pd.concat([train_df, test_df], axis=0).reset_index(drop=True)\n",
    "\n",
    "# 构建特征\n",
    "num_cols = ['airPressure','relativeHumidity','cloudiness','10mWindSpeed','10mWindDirection',\n",
    "            'temperature','irradiation','precipitation','100mWindSpeed','100mWindDirection']\n",
    "\n",
    "for col in tqdm.tqdm(num_cols):\n",
    "    # 历史平移/差分特征\n",
    "    for i in [1,2,3,4,5,6,7,15,30,50] + [1*96,2*96,3*96,4*96,5*96]:\n",
    "        df[f'{col}_shift{i}'] = df.groupby('stationId')[col].shift(i)\n",
    "        df[f'{col}_feture_shift{i}'] = df.groupby('stationId')[col].shift(-i)\n",
    "\n",
    "        df[f'{col}_diff{i}'] = df[f'{col}_shift{i}'] - df[col]\n",
    "        df[f'{col}_feture_diff{i}'] = df[f'{col}_feture_shift{i}'] - df[col]\n",
    "\n",
    "        df[f'{col}_2diff{i}'] = df.groupby('stationId')[f'{col}_diff{i}'].diff(1)\n",
    "        df[f'{col}_feture_2diff{i}'] = df.groupby('stationId')[f'{col}_feture_diff{i}'].diff(1)\n",
    "    \n",
    "    # 均值相关\n",
    "    df[f'{col}_3mean'] = (df[f'{col}'] + df[f'{col}_feture_shift1'] + df[f'{col}_shift1'])/3\n",
    "    df[f'{col}_5mean'] = (df[f'{col}_3mean']*3 + df[f'{col}_feture_shift2'] + df[f'{col}_shift2'])/5\n",
    "    df[f'{col}_7mean'] = (df[f'{col}_5mean']*5 + df[f'{col}_feture_shift3'] + df[f'{col}_shift3'])/7\n",
    "    df[f'{col}_9mean'] = (df[f'{col}_7mean']*7 + df[f'{col}_feture_shift4'] + df[f'{col}_shift4'])/9\n",
    "    df[f'{col}_11mean'] = (df[f'{col}_9mean']*9 + df[f'{col}_feture_shift5'] + df[f'{col}_shift5'])/11\n",
    "    \n",
    "    df[f'{col}_shift_3_96_mean'] = (df[f'{col}_shift{1*96}'] + df[f'{col}_shift{2*96}'] + df[f'{col}_shift{3*96}'])/3\n",
    "    df[f'{col}_shift_5_96_mean'] = (df[f'{col}_shift_3_96_mean']*3 + df[f'{col}_shift{4*96}'] + df[f'{col}_shift{5*96}'])/5\n",
    "    df[f'{col}_future_shift_3_96_mean'] = (df[f'{col}_feture_shift{1*96}'] + df[f'{col}_feture_shift{2*96}'] + df[f'{col}_feture_shift{3*96}'])/3\n",
    "    df[f'{col}_future_shift_5_96_mean'] = (df[f'{col}_future_shift_3_96_mean']*3 + df[f'{col}_feture_shift{4*96}'] + df[f'{col}_feture_shift{5*96}'])/3\n",
    "    \n",
    "    # 窗口统计\n",
    "    for win in [3,5,7,14,28]:\n",
    "        df[f'{col}_win{win}_mean'] = df.groupby('stationId')[col].rolling(window=win, min_periods=3, closed='left').mean().values\n",
    "        df[f'{col}_win{win}_max'] = df.groupby('stationId')[col].rolling(window=win, min_periods=3, closed='left').max().values\n",
    "        df[f'{col}_win{win}_min'] = df.groupby('stationId')[col].rolling(window=win, min_periods=3, closed='left').min().values\n",
    "        df[f'{col}_win{win}_std'] = df.groupby('stationId')[col].rolling(window=win, min_periods=3, closed='left').std().values\n",
    "        df[f'{col}_win{win}_skew'] = df.groupby('stationId')[col].rolling(window=win, min_periods=3, closed='left').skew().values\n",
    "        df[f'{col}_win{win}_kurt'] = df.groupby('stationId')[col].rolling(window=win, min_periods=3, closed='left').kurt().values\n",
    "        df[f'{col}_win{win}_median'] = df.groupby('stationId')[col].rolling(window=win, min_periods=3, closed='left').median().values\n",
    "        \n",
    "        df = df.sort_values(['stationId','time'], ascending=False)\n",
    "        \n",
    "        df[f'{col}_future_win{win}_mean'] = df.groupby('stationId')[col].rolling(window=win, min_periods=3, closed='left').mean().values\n",
    "        df[f'{col}_future_win{win}_max'] = df.groupby('stationId')[col].rolling(window=win, min_periods=3, closed='left').max().values\n",
    "        df[f'{col}_future_win{win}_min'] = df.groupby('stationId')[col].rolling(window=win, min_periods=3, closed='left').min().values\n",
    "        df[f'{col}_future_win{win}_std'] = df.groupby('stationId')[col].rolling(window=win, min_periods=3, closed='left').std().values\n",
    "        df[f'{col}_future_win{win}_skew'] = df.groupby('stationId')[col].rolling(window=win, min_periods=3, closed='left').skew().values\n",
    "        df[f'{col}_future_win{win}_kurt'] = df.groupby('stationId')[col].rolling(window=win, min_periods=3, closed='left').kurt().values\n",
    "        df[f'{col}_future_win{win}_median'] = df.groupby('stationId')[col].rolling(window=win, min_periods=3, closed='left').median().values\n",
    "        \n",
    "        df = df.sort_values(['stationId','time'], ascending=True)\n",
    "        \n",
    "        # 二阶特征\n",
    "        df[f'{col}_win{win}_mean_loc_diff'] = df[col] - df[f'{col}_win{win}_mean']\n",
    "        df[f'{col}_win{win}_max_loc_diff'] = df[col] - df[f'{col}_win{win}_max']\n",
    "        df[f'{col}_win{win}_min_loc_diff'] = df[col] - df[f'{col}_win{win}_min']\n",
    "        df[f'{col}_win{win}_median_loc_diff'] = df[col] - df[f'{col}_win{win}_median']\n",
    "        \n",
    "        df[f'{col}_future_win{win}_mean_loc_diff'] = df[col] - df[f'{col}_future_win{win}_mean']\n",
    "        df[f'{col}_future_win{win}_max_loc_diff'] = df[col] - df[f'{col}_future_win{win}_max']\n",
    "        df[f'{col}_future_win{win}_min_loc_diff'] = df[col] - df[f'{col}_future_win{win}_min']\n",
    "        df[f'{col}_future_win{win}_median_loc_diff'] = df[col] - df[f'{col}_future_win{win}_median']\n",
    "        \n",
    "for col in ['is_precipitation']:\n",
    "    for win in [4,8,12,20,48,96]:\n",
    "        df[f'{col}_win{win}_mean'] = df.groupby('stationId')[col].rolling(window=win, min_periods=3, closed='left').mean().values\n",
    "        df[f'{col}_win{win}_sum'] = df.groupby('stationId')[col].rolling(window=win, min_periods=3, closed='left').sum().values"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "ee7d1d72-e6cd-466b-b144-c1d0a04066f2",
   "metadata": {},
   "outputs": [],
   "source": [
    "train_df = df[df.is_test==0].reset_index(drop=True)\n",
    "test_df = df[df.is_test==1].reset_index(drop=True)\n",
    "del df\n",
    "gc.collect()\n",
    "\n",
    "train_df = train_df[train_df['power']!='<NULL>'].reset_index(drop=True)\n",
    "train_df['power'] = train_df['power'].astype(float)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "b3f70730-e92d-4602-98f3-9fa6c44b40d4",
   "metadata": {},
   "outputs": [],
   "source": [
    "cols = [f for f in test_df.columns if f not in ['time','power','is_test']] # capacity"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "61fb551d-3bfa-423e-980c-a7f3b5b9c893",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "************************************ 1 ************************************\n",
      "Training until validation scores don't improve for 200 rounds\n",
      "[500]\ttraining's rmse: 0.0168434\tvalid_1's rmse: 0.0439385\n",
      "[1000]\ttraining's rmse: 0.00705958\tvalid_1's rmse: 0.0410512\n",
      "[1500]\ttraining's rmse: 0.00332822\tvalid_1's rmse: 0.0403323\n",
      "[2000]\ttraining's rmse: 0.00164728\tvalid_1's rmse: 0.0400931\n",
      "[2500]\ttraining's rmse: 0.000833507\tvalid_1's rmse: 0.040002\n",
      "[3000]\ttraining's rmse: 0.00042521\tvalid_1's rmse: 0.0399645\n",
      "Did not meet early stopping. Best iteration is:\n",
      "[3000]\ttraining's rmse: 0.00042521\tvalid_1's rmse: 0.0399645\n",
      "[0.14863146452258852]\n",
      "                                   feature  importance_gain  importance_split  \\\n",
      "1795                  100mWindSpeed_11mean     31954.509318               221   \n",
      "1846                100mWindSpeed_win7_min      6194.671259               159   \n",
      "1866              100mWindSpeed_win14_mean      4725.590810               178   \n",
      "1738           100mWindSpeed_feture_shift7       714.365026               332   \n",
      "1794                   100mWindSpeed_9mean      1859.303510               112   \n",
      "1732           100mWindSpeed_feture_shift6       587.108547               264   \n",
      "1897        100mWindSpeed_future_win28_min       319.636009               423   \n",
      "91                      airPressure_diff96       169.962861               761   \n",
      "1895       100mWindSpeed_future_win28_mean       404.456860               310   \n",
      "1744          100mWindSpeed_feture_shift15       196.231441               587   \n",
      "1894            100mWindSpeed_win28_median       334.145978               335   \n",
      "148   airPressure_future_win3_min_loc_diff       710.070115               140   \n",
      "1726           100mWindSpeed_feture_shift5       395.873709               225   \n",
      "1868               100mWindSpeed_win14_min       273.223343               293   \n",
      "1576                precipitation_shift480        91.869566               795   \n",
      "24                                time_day       117.080667               585   \n",
      "1888              100mWindSpeed_win28_mean       263.334887               255   \n",
      "1578                 precipitation_diff480        96.589134               692   \n",
      "1896        100mWindSpeed_future_win28_max       139.868391               452   \n",
      "1560                 precipitation_diff192        96.358610               636   \n",
      "85                      airPressure_diff50        81.041012               730   \n",
      "15              100mWindSpeed_10mWindSpeed        58.441137              1004   \n",
      "1872            100mWindSpeed_win14_median       323.922881               177   \n",
      "1554                  precipitation_diff96        85.978530               623   \n",
      "116             airPressure_feture_diff480        72.902557               729   \n",
      "850         10mWindSpeed_future_win28_mean       184.149999               268   \n",
      "98              airPressure_feture_diff192        68.492652               684   \n",
      "1889               100mWindSpeed_win28_max       113.614127               411   \n",
      "1160                   temperature_diff480        54.087115               847   \n",
      "1570                precipitation_shift384        69.466419               659   \n",
      "\n",
      "               mul  \n",
      "1795  7.061947e+06  \n",
      "1846  9.849527e+05  \n",
      "1866  8.411552e+05  \n",
      "1738  2.371692e+05  \n",
      "1794  2.082420e+05  \n",
      "1732  1.549967e+05  \n",
      "1897  1.352060e+05  \n",
      "91    1.293417e+05  \n",
      "1895  1.253816e+05  \n",
      "1744  1.151879e+05  \n",
      "1894  1.119389e+05  \n",
      "148   9.940982e+04  \n",
      "1726  8.907158e+04  \n",
      "1868  8.005444e+04  \n",
      "1576  7.303631e+04  \n",
      "24    6.849219e+04  \n",
      "1888  6.715040e+04  \n",
      "1578  6.683968e+04  \n",
      "1896  6.322051e+04  \n",
      "1560  6.128408e+04  \n",
      "85    5.915994e+04  \n",
      "15    5.867490e+04  \n",
      "1872  5.733435e+04  \n",
      "1554  5.356462e+04  \n",
      "116   5.314596e+04  \n",
      "850   4.935220e+04  \n",
      "98    4.684897e+04  \n",
      "1889  4.669541e+04  \n",
      "1160  4.581179e+04  \n",
      "1570  4.577837e+04  \n",
      "************************************ 2 ************************************\n",
      "Training until validation scores don't improve for 200 rounds\n",
      "[500]\ttraining's rmse: 0.0167812\tvalid_1's rmse: 0.0437087\n",
      "[1000]\ttraining's rmse: 0.00706544\tvalid_1's rmse: 0.040943\n",
      "[1500]\ttraining's rmse: 0.00333047\tvalid_1's rmse: 0.0402528\n",
      "[2000]\ttraining's rmse: 0.00165028\tvalid_1's rmse: 0.0400237\n",
      "[2500]\ttraining's rmse: 0.00083572\tvalid_1's rmse: 0.0399331\n",
      "[3000]\ttraining's rmse: 0.000429049\tvalid_1's rmse: 0.0398961\n",
      "Did not meet early stopping. Best iteration is:\n",
      "[3000]\ttraining's rmse: 0.000429049\tvalid_1's rmse: 0.0398961\n",
      "[0.14863146452258852, 0.149687210406525]\n",
      "************************************ 3 ************************************\n",
      "Training until validation scores don't improve for 200 rounds\n",
      "[500]\ttraining's rmse: 0.0168281\tvalid_1's rmse: 0.0440828\n",
      "[1000]\ttraining's rmse: 0.007091\tvalid_1's rmse: 0.0412199\n",
      "[1500]\ttraining's rmse: 0.00333484\tvalid_1's rmse: 0.0404672\n",
      "[2000]\ttraining's rmse: 0.00164837\tvalid_1's rmse: 0.0402314\n",
      "[2500]\ttraining's rmse: 0.000835219\tvalid_1's rmse: 0.0401391\n",
      "[3000]\ttraining's rmse: 0.000428735\tvalid_1's rmse: 0.0401016\n",
      "Did not meet early stopping. Best iteration is:\n",
      "[3000]\ttraining's rmse: 0.000428735\tvalid_1's rmse: 0.0401016\n",
      "[0.14863146452258852, 0.149687210406525, 0.1528133447590343]\n",
      "************************************ 4 ************************************\n",
      "Training until validation scores don't improve for 200 rounds\n",
      "[500]\ttraining's rmse: 0.0167894\tvalid_1's rmse: 0.0437051\n",
      "[1000]\ttraining's rmse: 0.00706864\tvalid_1's rmse: 0.0408068\n",
      "[1500]\ttraining's rmse: 0.00333929\tvalid_1's rmse: 0.040106\n",
      "[2000]\ttraining's rmse: 0.00165092\tvalid_1's rmse: 0.0398748\n",
      "[2500]\ttraining's rmse: 0.000836742\tvalid_1's rmse: 0.0397838\n",
      "[3000]\ttraining's rmse: 0.000429532\tvalid_1's rmse: 0.0397469\n",
      "Did not meet early stopping. Best iteration is:\n",
      "[3000]\ttraining's rmse: 0.000429532\tvalid_1's rmse: 0.0397469\n",
      "[0.14863146452258852, 0.149687210406525, 0.1528133447590343, 0.15187466825064788]\n",
      "************************************ 5 ************************************\n",
      "Training until validation scores don't improve for 200 rounds\n",
      "[500]\ttraining's rmse: 0.0167838\tvalid_1's rmse: 0.043631\n",
      "[1000]\ttraining's rmse: 0.0070664\tvalid_1's rmse: 0.0408422\n",
      "[1500]\ttraining's rmse: 0.00334077\tvalid_1's rmse: 0.0401345\n",
      "[2000]\ttraining's rmse: 0.00165022\tvalid_1's rmse: 0.0398971\n",
      "[2500]\ttraining's rmse: 0.000837792\tvalid_1's rmse: 0.039808\n",
      "[3000]\ttraining's rmse: 0.000430624\tvalid_1's rmse: 0.0397709\n",
      "Did not meet early stopping. Best iteration is:\n",
      "[3000]\ttraining's rmse: 0.000430624\tvalid_1's rmse: 0.0397709\n",
      "[0.14863146452258852, 0.149687210406525, 0.1528133447590343, 0.15187466825064788, 0.1482421722556976]\n"
     ]
    }
   ],
   "source": [
    "def cv_model(clf, train_x, train_y, test_x, capacity, seed=2024):\n",
    "    folds = 5\n",
    "    kf = KFold(n_splits=folds, shuffle=True, random_state=seed)\n",
    "    oof = np.zeros(train_x.shape[0])\n",
    "    test_predict = np.zeros(test_x.shape[0])\n",
    "    cv_scores = []\n",
    "    \n",
    "    for i, (train_index, valid_index) in enumerate(kf.split(train_x, train_y)):\n",
    "        print('************************************ {} ************************************'.format(str(i+1)))\n",
    "        trn_x, trn_y, val_x, val_y = train_x.iloc[train_index], train_y[train_index], train_x.iloc[valid_index], train_y[valid_index]\n",
    "        \n",
    "        # 转化目标,进行站点目标归一化\n",
    "        trn_y = trn_y / capacity[train_index]\n",
    "        val_y = val_y / capacity[valid_index]\n",
    "        \n",
    "        train_matrix = clf.Dataset(trn_x, label=trn_y)\n",
    "        valid_matrix = clf.Dataset(val_x, label=val_y)\n",
    "        params = {\n",
    "            'boosting_type': 'gbdt',\n",
    "            'objective': 'regression',\n",
    "            'metric': 'rmse',\n",
    "            'min_child_weight': 5,\n",
    "            'num_leaves': 2 ** 8,\n",
    "            'lambda_l2': 10,\n",
    "            'feature_fraction': 0.8,\n",
    "            'bagging_fraction': 0.8,\n",
    "            'bagging_freq': 4,\n",
    "            'learning_rate': 0.1,\n",
    "            'seed': 2023,\n",
    "            'nthread' : 16,\n",
    "            'verbose' : -1,\n",
    "        }\n",
    "        model = clf.train(params, train_matrix, 3000, valid_sets=[train_matrix, valid_matrix],\n",
    "                          categorical_feature=[], verbose_eval=500, early_stopping_rounds=200)\n",
    "        val_pred = model.predict(val_x, num_iteration=model.best_iteration)\n",
    "        test_pred = model.predict(test_x, num_iteration=model.best_iteration)\n",
    "        \n",
    "        oof[valid_index] = val_pred\n",
    "        test_predict += test_pred / kf.n_splits\n",
    "        \n",
    "        score = 1/(1+np.sqrt(mean_squared_error(val_pred * capacity[valid_index], val_y * capacity[valid_index])))\n",
    "        cv_scores.append(score)\n",
    "        print(cv_scores)\n",
    "        \n",
    "        if i == 0:\n",
    "            imp_df = pd.DataFrame()\n",
    "            imp_df[\"feature\"] = cols\n",
    "            imp_df[\"importance_gain\"] = model.feature_importance(importance_type='gain')\n",
    "            imp_df[\"importance_split\"] = model.feature_importance(importance_type='split')\n",
    "            imp_df[\"mul\"] = imp_df[\"importance_gain\"]*imp_df[\"importance_split\"]\n",
    "            imp_df = imp_df.sort_values(by='mul',ascending=False)\n",
    "            imp_df.to_csv('feature_importance.csv', index=False)\n",
    "            print(imp_df[:30])\n",
    "            \n",
    "    return oof, test_predict\n",
    "\n",
    "lgb_oof, lgb_test = cv_model(lgb, train_df[cols], train_df['power'], test_df[cols], train_df['capacity'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "daa8ea52-f934-45d4-913b-81673cfa26f5",
   "metadata": {},
   "outputs": [],
   "source": [
    "submit_example['出力(MW)'] = lgb_test * test_df['capacity']\n",
    "submit_example.to_csv('final_result.csv', index=False)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "92dc4252-c8de-440d-8f79-9a35cd9d99cf",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "51491da8-be86-40a4-a20e-e5c5c197c760",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.13"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
